import re
import datetime

from .basic import BasicSchema
from ..db import DB

from telethon.tl.functions.channels import JoinChannelRequest, LeaveChannelRequest
from telethon.tl.functions.messages import GetBotCallbackAnswerRequest


class Channel_Loop(BasicSchema):
    def __init__(self, client, new_client, turple_rounds, CONST_NAMED_BOT):
        super().__init__(client, new_client, turple_rounds, CONST_NAMED_BOT)

    async def loop(self):
        self.logging.info("Started miner channels")
        while True:
            self.logging.info("New channel circle")
            await self.rand_sleep(1, 3)
            allmsg = await self.client.get_messages(self.tegmo, limit=2)
            msg = allmsg[0]
            if self.round_loop > self.CONST_ROUNDS_TO_SLEEP:
                self.round_loop = 0
                self.logging.info("Sleep for many round")
                await self.rand_sleep(3600, 3600)
            self.round_loop += 1
            if re.search(r"\bYou must join\b", msg.message):
                try:
                    entity = await self.client.get_entity(
                        msg.reply_markup.rows[0].buttons[0].url
                    )
                except:
                    self.logging.info(
                        f"Skip not found, {msg.reply_markup.rows[0].buttons[0].url}"
                    )
                    button_data = msg.reply_markup.rows[1].buttons[1].data
                    message_id = msg.id
                    await self.client(
                        GetBotCallbackAnswerRequest(
                            self.tegmo, message_id, data=button_data
                        )
                    )
                    continue
                try:
                    self.logging.info("Try join to channel.")
                    await self.rand_sleep(2, 3)
                    await self.client(JoinChannelRequest(entity.id))
                    self.logging.info("Successful join")
                except Exception as e:
                    self.logging.info("Fail")
                    self.logging.exception(e)
                    self.logging.error("Cancel channel loop...")
                    return self.total_sorry_round, self.round_loop
                button_data = msg.reply_markup.rows[0].buttons[1].data
                message_id = msg.id
                await self.client(
                    GetBotCallbackAnswerRequest(
                        self.tegmo, message_id, data=button_data
                    )
                )
                response_msg = await self.client.get_messages(self.tegmo, limit=2)
                if re.search(r"We cannot find", response_msg[-1].message):
                    button_data = response_msg[-1].reply_markup.rows[1].buttons[1].data
                    message_id = response_msg[-1].id
                    await self.client(LeaveChannelRequest(entity.id))
                    await self.client(
                        GetBotCallbackAnswerRequest(
                            self.tegmo, message_id, data=button_data
                        )
                    )
                    continue
                try:
                    self.logging.info(
                        f'New chat in message info about exit {response_msg[-1].message.encode()}, find {int(re.findall(r"([0-9]+)", response_msg[-1].message)[-1])}'
                    )
                    expire = datetime.timedelta(
                        hours=int(re.findall(r"([0-9]+)", response_msg[-1].message)[-1])
                    )
                except:
                    await self.client(LeaveChannelRequest(entity.id))
                    self.logging.info("Error get time, exit from channel")
                    button_data = msg.reply_markup.rows[0].buttons[1].data
                    message_id = msg.id
                    await self.client(
                        GetBotCallbackAnswerRequest(
                            self.tegmo, message_id, data=button_data
                        )
                    )
                    continue
                self.logging.info("Write channel to db")
                await DB.save_channel(f"{entity.id}|{datetime.datetime.now() + expire}")
            elif re.search(r"Sorry", msg.message):
                if self.total_sorry_round > 25:
                    self.total_sorry_round = 0
                    self.logging.info("Sleep for many sorry responses..")
                    await self.rand_sleep(
                        self.CONST_SORRY_SLEEP, self.CONST_SORRY_SLEEP
                    )
                    continue
                elif self.sorry_round > 5:
                    self.sorry_round = 0
                    return self.total_sorry_round, self.round_loop
                else:
                    self.sorry_round += 1
                    self.total_sorry_round += 1
                    await self.client.send_message(
                        f"{self.CONST_NAMED_BOT} Click Bot", "/join"
                    )
                    continue
            else:
                await self.client.send_message(
                    f"{self.CONST_NAMED_BOT} Click Bot", "/join"
                )
